home *** CD-ROM | disk | FTP | other *** search
AMOS Source Code | 1997-08-22 | 10.7 KB | 493 lines |
- ' RayCaster 3D engine for DoubleClick Issue 4
- ' �1997 Mark Harman
- ' You may use/modify this code as you wish
-
- Set Buffer 160
- Degree
-
- _SW=160 : Rem screen width
- _SH=_SW/1.6 : Rem screen height
-
- Dim _SIN(4096),_COS(4096),_COSEC(4096),_SEC(4096) : Rem tables for sin, cosine, cosec and sec
- Dim _DIST(4096,4) : Rem 0,1=x,y, 2=dist 3=map, 4=sliv - speed up
- _MX=32 : _MY=32 : Rem size of map in 'blocks'
- Dim _MAP(_MX,_MY) : Rem Map data
-
- 'set initial variables
- BSIZE=80 : Rem size of each block or square
- YHEIGHT=0 : Rem NOT USED at the moment
- HALFBSIZE=BSIZE/2 : Rem Precalculated for extra speed
- _LIGHTDIST=6*BSIZE : Rem Viewing distance
- DEGANG=180 : Rem Initial View Direction in DEGREES
- _ANGOA=0 : Rem NOT USED at the moment
- POSX=BSIZE+HALFBSIZE : Rem player's x pos
- POSY=BSIZE+HALFBSIZE : Rem and y pos
- _SCX=0 : Rem NOT USED
- _SCY=100 : Rem NOT USED
- _WALLHEIGHT=BSIZE*128*_SH : Rem height of a wall (independant of distance)
- '_DUCKED=0
-
- Gosub _CALCTABLES
- Gosub _GETMAP
-
- Screen Open 0,320,200,16,Lowres
- Paper 0 : Cls : Flash Off : Curs Off
- Double Buffer : Autoback 0
- Gosub _GETRAINBOW
- Screen Open 1,320,200,16,Lowres
- Screen Hide 1
- Paper 0 : Cls : Flash Off : Curs Off
- Dim _BOBX(Length(1)),_BOBY(Length(1))
- For K=1 To Length(1)
- X=((K-1) mod 5)*BSIZE
- Y=(K-1)/5*BSIZE
- Paste Bob X,Y,K
- _BOBX(K)=X
- _BOBY(K)=Y
- Next
- Screen 0
- Colour 3,0
-
- _MLOOP:
- PIXSX=2
- If Prg State=-1
- PIXSX=2
- End If
- _FRAMERATE=-1
- ' Rate at 160x100, PX1
-
- _XBOUNDSTART=POSX/BSIZE*BSIZE
- _YBOUNDSTART=POSY/BSIZE*BSIZE
- Do
- 'draw screen
- Timer=0
- Ink 0
- Extension_12_01A0 0,0
- Extension_12_01B0 _SW,200
- DANG=-_HSW+_ANGLES
- For VX=0 To _SW-1 Step PIXSX
- 'DANG=VX-_HSW
- 'DANG=((2.0*VX)/_SW-1)*_VIEWANG
- 'DDANG=(((2.0*VX)/_SW-1)*_VIEWANGDEG)
- CANG=(ANG+DANG+ANGOA+_ANGLES) mod _ANGLES
- _NEWCAST[POSX,POSY,CANG]
- 'DANG=(DANG+_ANGLES) mod _ANGLES
- NEWCAST=Max(NEWCAST,1)
- 'NHS=_WALLHEIGHT/(Max(NEWCAST*_COS(DANG),512))
- NHS=_WALLHEIGHT/(NEWCAST*_COS(DANG))
-
- '_WALLY=_HSH+YHEIGHT/NEWCAST
- ' If _WALLY-NHS>=0 and _WALLY+NHS<_SH and NEWCAST<=_LIGHTDIST
- If _HSH-NHS>=0 and _HSH+NHS<_SH and NEWCAST<=_LIGHTDIST
- X=_BOBX(MAP)
- Y=_BOBY(MAP)
- 'Zoom 1,X+SLIV,Y,X+SLIV+1,Y+BSIZE-1 To 0,VX,_WALLY-NHS,VX+PIXSX,_WALLY+NHS
- Zoom 1,X+SLIV,Y,X+SLIV+1,Y+BSIZE-1 To 0,VX,_HSH-NHS,VX+PIXSX,_HSH+NHS
- '_ZOOM[1,SLIV,0,SLIV+1,31,0,VX,100-NHS,VX+PIXSX,100+NHS]
- Else
- If NEWCAST>_LIGHTDIST
- Ink 3
- Extension_12_01A0 VX,_HSH-NHS
- Extension_12_01B0 PIXSX,2*NHS
- Else
- X=_BOBX(MAP)
- Y=_BOBY(MAP)+HALFBSIZE
- ZDY=Max(1,(HALFBSIZE*_HSH)/NHS)
- Zoom 1,X+SLIV,Y-ZDY,X+SLIV+1,Y+ZDY-1 To 0,VX,0,VX+PIXSX,_SH
- End If
- End If
-
- Add DANG,PIXSX,0 To _ANGLES-PIXSX
- Next
- TIME=Timer
- If _FRAMERATE=-1
- Trap Print 50.0/TIME
- Home
- End If
- Screen Swap
- Wait Vbl
- If Key Shift and 3
- SHIFT=4
- Else
- SHIFT=2
- End If
- If Key Shift and 192
- SIDE=1
- Else
- SIDE=0
- End If
- If Key State(79)
- 'left
- If SIDE=0
- Add ANG,-4*TIME
- If ANG<0
- Add ANG,_ANGLES
- End If
- Else
- DX=-(_COS(ANG)*TIME*SHIFT)/340
- DY=-(_SIN(ANG)*TIME*SHIFT)/340
- NX=POSX+DX
- NY=POSY+DY
- Gosub _CHECKMOVE
- End If
- Else If Key State(78)
- 'right
- If SIDE=0
- Add ANG,4*TIME
- If ANG>=_ANGLES
- Add ANG,-_ANGLES
- End If
- Else
- DX=(_COS(ANG)*TIME*SHIFT)/680
- DY=(_SIN(ANG)*TIME*SHIFT)/680
- NX=POSX+DX
- NY=POSY+DY
- Gosub _CHECKMOVE
- End If
- End If
- If Key State(76)
- 'forward
- 'If _DUCKED=0
- 'Add YHEIGHT,300,0 To 300
- 'Else
- 'SHIFT=SHIFT/2
- 'End If
- DX=(_SIN(ANG)*TIME*SHIFT)/340
- DY=-(_COS(ANG)*TIME*SHIFT)/340
- NX=POSX+DX
- NY=POSY+DY
- Gosub _CHECKMOVE
- Else If Key State(77)
- 'backwards
- 'If _DUCKED=0
- 'Add YHEIGHT,300,0 To 300
- 'Else
- 'SHIFT=SHIFT/2
- 'End If
- DX=-(_SIN(ANG)*TIME*SHIFT)/340
- DY=(_COS(ANG)*TIME*SHIFT)/340
- NX=POSX+DX
- NY=POSY+DY
- Gosub _CHECKMOVE
- End If
- ANGOA=0
- If Key State(40)
- ANGOA=_VIEWQ2
- End If
- If Key State(34)
- _DUCKED=-1-_DUCKED
- YHEIGHT=_DUCKED*800
- End If
- If Key State(90)
- PIXSX=1
- Else If Key State(91)
- PIXSX=2
- Else If Key State(92)
- PIXSX=4
- Else If Key State(93)
- PIXSX=8
- Else If Key State(74)
- Add _SW,-16,80 To 320
- Add _SH,-10,50 To 200
- Gosub _CALCTABLES
- Cls : Screen Swap : Cls
- Gosub _GETRAINBOW
- Else If Key State(94)
- Add _SW,16,80 To 320
- Add _SH,10,50 To 200
- Gosub _CALCTABLES
- Cls : Screen Swap : Cls
- Gosub _GETRAINBOW
- End If
- Loop
- 'T=Timer
- 'Print(_NFRAMES*50.0)/T
- 'Screen Swap
- End
-
- _CALCTABLES:
- _HSW=_SW/2
- _HSH=_SH/2
- _VIEWANGDEG=90
- If _ANGLES<>0
- DEGANG=(ANG*360)/_ANGLES
- End If
- _ANGLES=(360*_SW)/_VIEWANGDEG
- ANG=(DEGANG*_ANGLES)/360
- _VIEWANG=(_ANGLES*_VIEWANGDEG)/360
- _VIEWQ1=_ANGLES/4
- _VIEWQ2=2*_ANGLES/4
- _VIEWQ3=3*_ANGLES/4
-
- STP#=360.0/_ANGLES
- CURRANG=0
- For K#=0.0 To 360 Step STP#
- S#=Sin(K#)
- C#=Cos(K#)
- _SIN(CURRANG)=S#*512
- _COS(CURRANG)=C#*512
- If S#=0
- S#=0.009
- End If
- If C#=0
- C#=0.009
- End If
- _COSEC(CURRANG)=512/S#
- _SEC(CURRANG)=512/C#
-
- _DIST(CURRANG,0)=0
-
- Inc CURRANG
- Next
- Return
-
- _GETMAP:
- '1=Wall, 2=PSoft
-
- Restore _MAP1
- For Y=0 To _MY-1
- Read LINE$
- For X=0 To _MX-1
- MP$=Mid$(LINE$,X+1,1)
- MP=Val(MP$)
- _MAP(X,Y)=MP
- Next
- Next
-
- _MAP1:
- Data "11111111111111111111111111111111"
- Data "10100000100000110000111111111111"
- Data "10100000000000000000011111111111"
- Data "10100000100000110000111111111111"
- Data "10112110111111111111111111111111"
- Data "10000000000000000000000000000001"
- Data "11111011111111111111111110111101"
- Data "11100001100000000000001100011101"
- Data "11100001100001110000001100011101"
- Data "11100001100001110000001100011001"
- Data "11100001100011111111111111111001"
- Data "11111111110110000001111111110001"
- Data "11100011000000000000000000000001"
- Data "11100000000000000000000000000001"
- Data "11110111111011111111011111101111"
- Data "11110111111111111111111111111111"
- Data "11110111111111111111111111111111"
- Data "11110111111111111111111111111111"
- Data "11110000000000000000011111111111"
- Data "11111100000000000000011111111111"
- Data "11111100200000000020011111111111"
- Data "11111100000000000000011111111111"
- Data "11111100000011100000011111111111"
- Data "11111100000010100000011111111111"
- Data "11111100000000000000011111111111"
- Data "11111100200000000020011111111111"
- Data "11111100000000000000011111111111"
- Data "11111100000000000000011111111111"
- Data "11111111101111111011111111111111"
- Data "11111111000111110001111111111111"
- Data "11111111000111110001111111111111"
- Data "11111111111111111111111111111111"
-
- Return
-
- _GETRAINBOW:
- Clip 0,0 To _SW,_SH
- Rainbow Del 0
- Set Rainbow 0,0,_SH,"","",""
- For K=0 To _HSH-1
- C=(Ln(((K+1)*200)/_HSH)*2)
- C=Max(0,C-4)
- Rain(0,_HSH-1-K)=C*273+3
- Rain(0,_HSH+K)=C*273+544
- Next
- Rainbow 0,0,50,_SH
-
- Return
-
- _CHECKMOVE:
- OKAY=-1
- MAPX=NX/BSIZE
- MAPY=NY/BSIZE
- MP=_MAP(MAPX,MAPY)
- If MP>0
- OKAY=0
- 'put to furthest available
- 'If DY>0
- ' NY=(Y/BSIZE+1)*BSIZE-1
- 'End If
- 'OKAY=-1
- End If
-
- If OKAY=-1
- POSX=NX
- POSY=NY
- _XBOUNDSTART=POSX/BSIZE*BSIZE
- _YBOUNDSTART=POSY/BSIZE*BSIZE
- End If
-
- Return
-
- Procedure _NEWCAST[X,Y,ANG]
- Shared _COS(),_SIN(),_SEC(),_COSEC(),_DIST(),_ANGLES,_MAP(),BSIZE,HALFBSIZE,_LIGHTDIST
- Shared _VIEWQ1,_VIEWQ2,_VIEWQ3
- Shared _XBOUNDSTART,_YBOUNDSTART
-
- 'Shared XDEPTH,YDEPTH
-
- ' outputs:
- Shared NEWCAST,MAP,SLIV
-
- If _DIST(ANG,0)=X and _DIST(ANG,1)=Y
- NEWCAST=_DIST(ANG,2)
- MAP=_DIST(ANG,3)
- SLIV=_DIST(ANG,4)
- Pop Proc
- End If
- 'ANGLE=(ANG+_ANGLES) mod _ANGLES
- 'Cls
- 'Print ANG,ANGLE
- 'Wait Key
- ANGLE=ANG
- CORNER=0
- If ANG>_VIEWQ1 and ANG<_VIEWQ3
- YADJ=HALFBSIZE
- Else
- YADJ=-HALFBSIZE
- End If
- If ANG>0 and ANG<_VIEWQ2
- XADJ=HALFBSIZE
- Else
- XADJ=-HALFBSIZE
- End If
-
- 'pre-calc
- _CANG=_COS(ANGLE)
- _SANG=_SIN(ANGLE)
- _CANGR=_SEC(ANGLE)
- _SANGR=_COSEC(ANGLE)
- 'x casting
- If _CANG=0
- XDEPTH=1E+09
- Else
- If ANG>_VIEWQ1 and ANG<_VIEWQ3
- YBOUND=_YBOUNDSTART+BSIZE
- YDELTA=BSIZE
- Else
- YBOUND=_YBOUNDSTART
- YDELTA=-BSIZE
- End If
- Do
-
- YDIST=YBOUND-Y
- DEPTH=(YDIST*_CANGR)/512
- XDIST=(DEPTH*_SANG)/512
- DX=(X-XDIST)/BSIZE
- ADEPTH=Abs(DEPTH)
- If ADEPTH>_LIGHTDIST
- XDEPTH=ADEPTH
- Exit
- End If
- If DX>=0 and DX<32
- MP=_MAP(DX,(YBOUND+YADJ)/BSIZE)
- If MP>0
- XDEPTH=ADEPTH
- XSLIV=Abs(X-XDIST) mod BSIZE
- XMP=MP
- Exit
- Else
- Add YBOUND,YDELTA
- End If
- Else
- XDEPTH=1E+06
- Exit
- End If
- Loop
- End If
-
- 'y casting
- If _SANG=0
- YDEPTH=1E+06
- Else
- If ANG>0 and ANG<_VIEWQ2
- XBOUND=_XBOUNDSTART+BSIZE
- XDELTA=BSIZE
- Else
- XBOUND=_XBOUNDSTART
- XDELTA=-BSIZE
- End If
- Do
- XDIST=XBOUND-X
- DEPTH=(XDIST*_SANGR)/512
- ADEPTH=Abs(DEPTH)
- If ADEPTH>_LIGHTDIST
- YDEPTH=ADEPTH
- Exit
- End If
- YDIST=(DEPTH*_CANG)/512
- DY=(Y-YDIST)/BSIZE
- If DY>=0 and DY<32
- MP=_MAP((XBOUND+XADJ)/BSIZE,DY)
- If MP>0
- YDEPTH=ADEPTH
- YSLIV=Abs(Y-YDIST) mod BSIZE
- YMP=MP
- Exit
- Else
- Add XBOUND,XDELTA
- End If
- Else
- YDEPTH=1E+06
- Exit
- End If
- Loop
- End If
-
- If XDEPTH<YDEPTH
- NEWCAST=XDEPTH
- SLIV=XSLIV
- MAP=XMP
- If XSLIV=0
- CORNER=-1
- End If
- Else
- NEWCAST=YDEPTH
- SLIV=YSLIV
- MAP=YMP
- If YSLIV=0
- CORNER=-1
- End If
- End If
-
- _DIST(ANG,0)=X
- _DIST(ANG,1)=Y
- _DIST(ANG,2)=NEWCAST
- _DIST(ANG,3)=MAP
- _DIST(ANG,4)=SLIV
- 'Print X,Y,ANG
- 'Print XDEPTH,YDEPTH,DEPTH,NEWCAST
- 'Print
-
- End Proc
-
- Procedure _CALC[YBOUND,Y,_CANG,_SANG,X,BSIZE]
- 'YDIST=YBOUND-Y'
- 'DEPTH=(YDIST*512)/_CANG
- 'XDIST=(DEPTH*_SANG)/512
- 'DX=(X-XDIST)/BSIZE
- Dreg(0)=YBOUND
- Dreg(6)=Y
- Dreg(5)=_CANG
- Dreg(2)=_SANG
- Dreg(1)=X
-
-
- Dreg(0)=Dreg(0)-Dreg(6)
- Dreg(0)=(Dreg(0)*512)/Dreg(5)
- Dreg(2)=(Dreg(0)*Dreg(2))/512
- Dreg(1)=(Dreg(1)-Dreg(2))/BSIZE
-
- 'DEPTH=Dreg(0)
- 'DX=Dreg(1)
- 'XDIST=Dreg(2)
-
- End Proc